package edu.suda.basic.acm;

import java.util.ArrayList;
import java.util.List;

public class GameState
{
	private GameState parentState;
	private GameState childState1;
	private GameState childState2;
	private GameState childState3;
	private GameState childState4;
	private GameState childState5;
	private GameState childState6;
	private static int capacityA;
	private static int capacityB;
	private int volumnA;
	private int volumnB;
	private boolean extensible=true;
	private String resultingOperation;
	private static List<GameState> knownStates=new ArrayList<GameState>();
	
	public String getResultingOperation()
	{
		return resultingOperation;
	}

	public void setResultingOperation(String resultingOperation)
	{
		this.resultingOperation = resultingOperation;
	}

	public GameState getParentState()
	{
		return parentState;
	}

	public void setParentState(GameState parentState)
	{
		this.parentState = parentState;
	}

	public boolean isExtensible()
	{
		return extensible;
	}

	public void setExtensible(boolean extensible)
	{
		this.extensible = extensible;
	}

	public static int getCapacityA()
	{
		return capacityA;
	}

	public static int getCapacityB()
	{
		return capacityB;
	}

	public int getVolumnA()
	{
		return volumnA;
	}
	public void setVolumnA(int volumnA)
	{
		this.volumnA = volumnA;
	}
	public int getVolumnB()
	{
		return volumnB;
	}
	public void setVolumnB(int volumnB)
	{
		this.volumnB = volumnB;
	}
	
	public GameState getChildState1()
	{
		return childState1;
	}

	public void setChildState1(GameState childState1)
	{
		this.childState1 = childState1;
	}

	public GameState getChildState2()
	{
		return childState2;
	}

	public void setChildState2(GameState childState2)
	{
		this.childState2 = childState2;
	}

	public GameState getChildState3()
	{
		return childState3;
	}

	public void setChildState3(GameState childState3)
	{
		this.childState3 = childState3;
	}

	public GameState getChildState4()
	{
		return childState4;
	}

	public void setChildState4(GameState childState4)
	{
		this.childState4 = childState4;
	}

	public GameState getChildState5()
	{
		return childState5;
	}

	public void setChildState5(GameState childState5)
	{
		this.childState5 = childState5;
	}

	public GameState getChildState6()
	{
		return childState6;
	}

	public void setChildState6(GameState childState6)
	{
		this.childState6 = childState6;
	}

	public static void setCapacityA(int capacityA)
	{
		GameState.capacityA = capacityA;
	}

	public static void setCapacityB(int capacityB)
	{
		GameState.capacityB = capacityB;
	}

	/**
	 * @param args
	 */
	public void grow()
	{
		if(this.extensible==false)
			return;
		//empty A
		GameState tmpGS=new GameState();
		tmpGS.setParentState(this);
		tmpGS.setVolumnA(0);
		tmpGS.setVolumnB(this.volumnB);
		tmpGS.setResultingOperation("清空A");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState1(tmpGS);
		
		//empty B
		tmpGS=new GameState();
		tmpGS.setParentState(this);
		tmpGS.setVolumnA(this.volumnA);
		tmpGS.setVolumnB(0);
		tmpGS.setResultingOperation("清空B");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState2(tmpGS);
		
		//fill A
		tmpGS=new GameState();
		tmpGS.setParentState(this);
		tmpGS.setVolumnA(GameState.capacityA);
		tmpGS.setVolumnB(this.volumnB);
		tmpGS.setResultingOperation("灌满A");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState3(tmpGS);
		
		//fill B
		tmpGS=new GameState();
		tmpGS.setParentState(this);
		tmpGS.setVolumnA(this.volumnA);
		tmpGS.setVolumnB(GameState.capacityB);
		tmpGS.setResultingOperation("灌满B");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState4(tmpGS);
		
		//A to B
		tmpGS=new GameState();
		tmpGS.setParentState(this);
		if(this.volumnA+this.volumnB>=GameState.capacityB)
		{
			tmpGS.setVolumnB(GameState.capacityB);
			tmpGS.setVolumnA(this.volumnA+this.volumnB-GameState.capacityB);
		}
		else
		{
			tmpGS.setVolumnB(this.volumnA+this.volumnB);
			tmpGS.setVolumnA(0);
		}
		tmpGS.setResultingOperation("A倒入B");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState5(tmpGS);
		
		//B to A
		tmpGS=new GameState();
		tmpGS.setParentState(this);
		if(this.volumnA+this.volumnB>=GameState.capacityA)
		{
			tmpGS.setVolumnA(GameState.capacityA);
			tmpGS.setVolumnB(this.volumnA+this.volumnB-GameState.capacityA);
		}
		else
		{
			tmpGS.setVolumnB(0);
			tmpGS.setVolumnA(this.volumnA+this.volumnB);
		}
		tmpGS.setResultingOperation("B倒入A");
		tmpGS.setExtensible(GameState.isNewState(tmpGS));
		GameState.updateKnownStates(tmpGS);
		
		this.setChildState6(tmpGS);
	}
	public static void updateKnownStates(GameState newState)
	{
		if(GameState.isNewState(newState));
		{
			GameState.knownStates.add(newState);
		}
	}
	/*判断给定状态是否为新状态*/
	private static boolean isNewState(GameState gs)
	{
		boolean result=true;
		for(GameState tmp:GameState.knownStates)
		{
			//出现过，是旧状态，返回false
			if(gs.getVolumnA()==tmp.getVolumnA() && gs.getVolumnB()==tmp.getVolumnB())
				result=false;
		}
		return result;
	}
	
	public String getOpSeq()
	{
		StringBuffer sb=new StringBuffer();
		sb.append(this.getResultingOperation()).append(",").append("A=").append(this.volumnA).append(",B=").append(this.volumnB).append(";");
		GameState gs=this.getParentState();
		while(gs!=null)
		{
			sb.append(gs.getResultingOperation()).append(",").append("A=").append(gs.volumnA).append(",B=").append(gs.volumnB).append(";");
			gs=gs.getParentState();
		}
		String[] s=sb.toString().split(";");
		StringBuffer sb2=new StringBuffer();
		for(int i=s.length-1;i>=0;i--)
			sb2.append(s[i]).append(";");
		return sb2.toString();
	}
	public static void main(String[] args)
	{
	
		
	}

}
